package com.hmkj.web.controller.my;

import com.hmkj.common.entity.ResultEntity;
import com.hmkj.common.page.BasePageParams;
import com.hmkj.common.page.Pages;
import com.hmkj.common.utils.StringUtils;
import com.hmkj.common.utils.ValidateUtils;
import com.hmkj.core.constant.AliyunCodeKey;
import com.hmkj.core.constant.ConfigNID;
import com.hmkj.core.constant.PhoneCodeKey;
import com.hmkj.core.constant.SessionId;
import com.hmkj.core.exception.BussinessException;
import com.hmkj.core.mapper.user.UserMapper;
import com.hmkj.core.model.user.UserModel;
import com.hmkj.core.po.account.Account;
import com.hmkj.core.po.order.Order;
import com.hmkj.core.po.suggestion.Suggestion;
import com.hmkj.core.po.user.User;
import com.hmkj.core.po.user.UserNoticeSet;
import com.hmkj.core.po.userAuth.UserAuth;
import com.hmkj.core.po.userBank.UserBank;
import com.hmkj.core.service.account.AccountService;
import com.hmkj.core.service.order.OrderService;
import com.hmkj.core.service.suggestion.SuggestionService;
import com.hmkj.core.service.system.NoticeLogService;
import com.hmkj.core.service.user.UserNoticeSetService;
import com.hmkj.core.service.user.UserService;
import com.hmkj.core.service.userAuth.UserAuthService;
import com.hmkj.core.service.userBank.UserBankService;
import com.hmkj.web.controller.GenericController;
import com.xiaoleilu.hutool.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Administrator
 */
@Api(description = "用户中心相关")
@Slf4j
@RestController
@RequestMapping(GenericController.MEMBER_URL + "/user")
public class AppUserController extends GenericController<Integer, User> {

    @Resource
    private UserService userService;
    @Resource
    private UserBankService userBankService;
    @Resource
    private OrderService orderService;
    @Resource
    private AccountService accountService;
    @Resource
    private UserAuthService userAuthService;
    @Resource
    private SuggestionService suggestionService;
    @Resource
    private UserNoticeSetService userNoticeSetService;
    @Resource
    private NoticeLogService noticeLogService;

    @ApiOperation(value = "用户中心首页", notes = "用户中心首页")
    @ResponseBody
    @RequestMapping(value = "index", method = RequestMethod.POST)
    public ResultEntity index() {

        return ok(m -> {
            final User user = userService.selectByPrimaryKey(getLoginUser().getId());
            m.put("id", user.getId());
            m.put("mobile", user.getMobilePhone());
            m.put("avatarUrl", user.getAvatarUrl());
            m.put("userName", user.getUserName());
            m.put("userMobile", redisService.get(ConfigNID.SERVICE_PHONE));
            m.put("amount", accountService.selectOne(new Account(account -> {
                account.setUserId(user.getId());
                account.setDelFlag(Account.DELFLAG.NORMAL.code);
            })).getAvailable());
            m.put("moneyAvailable", accountService.selectOne(new Account(account -> {
                account.setUserId(user.getId());
                account.setDelFlag(Account.DELFLAG.NORMAL.code);
            })).getMoneyAvailable());
            m.put("generalizeCount", userService.selectCount(new User(t -> {
                t.setInviteId(user.getId());
            })));
            m.put("royalty", BigDecimal.ZERO);
        });
    }

    @ApiOperation(value = "我的消息推送列表", notes = "我的消息推送列表")
    @ResponseBody
    @RequestMapping(value = "messagePushList", method = RequestMethod.POST)
    public ResultEntity messagePushList() {
        User user = getLoginUser();
        List<UserNoticeSet> userNoticeSetList = userNoticeSetService.select(new UserNoticeSet(u -> {
            u.setUserId(user.getId());
        }));
        return ok(userNoticeSetList);
    }

    @ApiOperation(value = "消息推送编辑", notes = "消息推送编辑")
    @ResponseBody
    @RequestMapping(value = "/messagePushEdit", method = RequestMethod.POST)
    public ResultEntity messagePushEdit(
            @ApiParam("消息推送类型") @RequestParam Integer type,
            @ApiParam("启用类型: 1 推送，2 不推送") @RequestParam Integer type1) throws Exception {
        User user = getLoginUser();
        if (null == type || null == type1 || (type1 != 1 && type1 != 2)) {
            throw new BussinessException("参数错误");
        }
        if (type != 1 && type != 2 && type != 3 && type != 4 && type != 5 && type != 6) {
            throw new BussinessException("消息推送类型参数有误");
        }
        UserNoticeSet noticeSet = userNoticeSetService.selectOne(new UserNoticeSet(t -> {
            t.setUserId(user.getId());
        }));
        switch (type) {
            case 1:
                noticeSet.setSystemNo(type1);
                break;
            case 2:
                noticeSet.setDiyanNo(type1);
                break;
            case 3:
                noticeSet.setCoverNo(type1);
                break;
            case 4:
                noticeSet.setStopLossNo(type1);
                break;
            case 5:
                noticeSet.setStopProfitNo(type1);
                break;
            case 6:
                noticeSet.setFollowNo(type1);
                break;
            default:
                break;
        }
        userNoticeSetService.updateByPrimaryKeySelective(noticeSet);
        return ok("修改成功", ResultEntity.SUCCESS);
    }


    @ApiOperation(value = "用户信息", notes = "用户信息")
    @ResponseBody
    @RequestMapping(value = "userInfo", method = RequestMethod.POST)
    public ResultEntity userInfo() {
        Map<String, Object> m = new HashMap<>();
        User user = getLoginUser();
        UserAuth userAuth = userAuthService.selectByUID(user.getId());
        List<UserBank> userBankList = userBankService.select(new UserBank(t -> {
            t.setUserId(user.getId());
            t.setStatus(UserBank.STATUS.T2.code);
            t.setDelFlag(UserBank.DELFLAG.NORMAL.code);
        }));
        m.put("id", user.getId());
        m.put("userName", user.getUserName());
        m.put("mobile", user.getMobilePhone());
        m.put("avatarUrl", user.getAvatarUrl());
        m.put("realNameStatus", null == userAuth ? 0 : userAuth.getAuthStatus());
        m.put("realName", null == userAuth ? "" : userAuth.getRealname());
        m.put("idCard", null == userAuth ? "" : userAuth.getIdcard());
        m.put("isSetPayPwd", StringUtils.isBlank(user.getPayPassword()) ? 0 : 1);
        m.put("bankCardSize", null == userBankList ? 0 : userBankList.size());
        return ok(m);
    }

    @ApiOperation(value = "修改头像", notes = "修改头像 /file/upload接口上传图片后会返回地址,把地址带到这个接口")
    @ResponseBody
    @RequestMapping(value = "avatar", method = RequestMethod.POST)
    public ResultEntity avatar(@ApiParam("头像地址") @RequestParam String avatarUrl) {
        User user = getLoginUser();
        user.setAvatarUrl(avatarUrl);
        setLoginUser(user);
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setAvatarUrl(avatarUrl);
        }));
        return ok(avatarUrl);
    }

//    @ApiOperation(value = "校验密码", notes = "校验密码")
//    @ResponseBody
//    @RequestMapping(value = "checkPwd", method = RequestMethod.POST)
//    public ResultEntity checkPwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String oldPwd) {
//
//        User user = userService.selectByPrimaryKey(getLoginUser().getId());
//        if (!user.getPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
//            throw new BussinessException("原密码错误");
//        }
//        return ok();
//    }

    @ApiOperation(value = "修改密码", notes = "修改密码")
    @ResponseBody
    @RequestMapping(value = "pwd", method = RequestMethod.POST)
    public ResultEntity pwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String oldPwd,
                            @ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) throws Exception {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (!user.getPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原密码错误");
        }
        UserModel.checkPwd(newPwd);
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok("修改密码成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改支付密码-校验手机号", notes = "修改支付密码-校验手机号")
    @ResponseBody
    @RequestMapping(value = "phoneSendMsg", method = RequestMethod.POST)
    public ResultEntity phoneSendMsg() throws Exception {
        sendSmsCode(AliyunCodeKey.RESET_PAY_PWD,"修改支付密码", getLoginUser().getMobilePhone());
        return ok("校验手机号成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改支付密码-校验短信", notes = "修改支付密码-校验短信")
    @ResponseBody
    @RequestMapping(value = "phoneCheckPaypwdMsg", method = RequestMethod.POST)
    public ResultEntity phoneCheckPaypwdMsg(@ApiParam("手机短信验证码") @RequestParam String msgCode) throws Exception {
        checkUserPhoneCode(getLoginUser().getMobilePhone(), msgCode, PhoneCodeKey.RESET_PAY_PWD);
        return ok("校验短信成功", ResultEntity.SUCCESS);
    }


    @ApiOperation(value = "校验支付密码", notes = "校验支付密码")
    @ResponseBody
    @RequestMapping(value = "checkPayPwd", method = RequestMethod.POST)
    public ResultEntity payPwd(@ApiParam("密码(rsa加密再base64加密)(未设置支付密码时可空)") @RequestParam String oldPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (!user.getPayPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原支付密码错误");
        }
        return ok("校验支付密码成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改/新增支付密码", notes = "修改/新增支付密码")
    @ResponseBody
    @RequestMapping(value = "payPwd", method = RequestMethod.POST)
    public ResultEntity payPwd(@ApiParam("密码(rsa加密再base64加密)(未设置支付密码时可空)") @RequestParam(required = false) String oldPwd,
                               @ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) {

        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        if (StrUtil.isNotBlank(user.getPayPassword()) && !user.getPayPassword().equals(UserModel.encodePwd(UserModel.staticDecryptPwd(oldPwd)))) {
            throw new BussinessException("原支付密码错误");
        }
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPayPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok("修改/新增支付密码成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "手机号验证修改支付密码", notes = "机号验证修改支付密码")
    @ResponseBody
    @RequestMapping(value = "phonePayPwd", method = RequestMethod.POST)
    public ResultEntity phonePayPwd(@ApiParam("密码(rsa加密再base64加密)") @RequestParam String newPwd) {
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPayPassword(UserModel.encodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        return ok("手机号验证修改支付密码成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "实名认证", notes = "实名认证")
    @ResponseBody
    @RequestMapping(value = "realName", method = RequestMethod.POST)
    public ResultEntity realName(@ApiParam("真实姓名") @RequestParam String realName,
                                 @ApiParam("身份证号码") @RequestParam String idCard
//                                 @ApiParam("身份证正面") @RequestParam String cardFront,
//                                 @ApiParam("身份证反面") @RequestParam String cardOpposite
    ) throws Exception {
        User user = userService.selectByPrimaryKey(getLoginUser().getId());
        //参数校验
        UserModel.checkRealName(realName, idCard);
        userAuthService.addRealNameAuth(user, realName, idCard);
        return ok("实名认证成功", ResultEntity.SUCCESS);
    }

//    @ApiOperation(value = "每日签到", notes = "每日签到")
//    @ResponseBody
//    @RequestMapping(value = "sign", method = RequestMethod.POST)
//    public ResultEntity sign() {
//        userService.doSign(getLoginUser().getId());
//        PointRule pointRule = pointRuleService.selectOne(new PointRule(t ->{
//            t.setNid(PointNid.T2.nid);
//            t.setStatus(PointRule.STATUS.T1.code);
//            t.setDelFlag(PointRule.DELFLAG.NORMAL.code);
//        }));
//        return ok("签到成功", null == pointRule ? 0:pointRule.getValue());
//    }
//
//    @ApiOperation(value = "用户可用/充值限制", notes = "用户可用/充值限制")
//    @ResponseBody
//    @RequestMapping(value = "rechargeLimit", method = RequestMethod.POST)
//    public ResultEntity rechargeLimit() {
//        User user = getLoginUser();
//        AccountModel accountModel = accountService.getAccountModel(user.getId());
//        return ok(m->{
//            m.put("rechargeMin", accountModel.getRechargeMin());
//            m.put("rechargeMax", accountModel.getRechargeMax());
//            m.put("available", accountModel.getAvailable());
//        });
//    }

    @ApiOperation(value = "修改用户名", notes = "修改用户名")
    @ResponseBody
    @RequestMapping(value = "modifyName", method = RequestMethod.POST)
    public ResultEntity modifyName(@ApiParam("用户名") @RequestParam String userName) throws Exception {
        User user = getLoginUser();
        if (StrUtil.isBlank(userName)) {
            throw new BussinessException("用户名不能为空");
        } else if (userName.length() > 50) {
            throw new BussinessException("用户名长度不能大于50位！");
        } else if (!ValidateUtils.isUserName(userName)) {
            throw new BussinessException("用户名必须是中英文或数字组合");
        }
        if (StringUtils.isNotBlank(user.getUserName())) {
            if (user.getUserName().equals(userName)) {
                return ok();
            }
        }
        int count = userService.selectCount(new User(t -> {
            t.setUserName(userName);
            t.setDelFlag(User.DELFLAG.NORMAL.code);
        }));
        if (count > 0) {
            throw new BussinessException("该用户名已存在");
        }
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setUserName(userName);
        }));
        return ok("修改用户名成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改手机号", notes = "修改手机号")
    @ResponseBody
    @RequestMapping(value = "phone", method = RequestMethod.POST)
    public ResultEntity phone(@ApiParam("老手机短信验证码") @RequestParam String msgCode,
                              @ApiParam("新手机号") @RequestParam String newPhone,
                              @ApiParam("新手机短信验证码") @RequestParam String newMsgCode) {
        final User user = getLoginUser();
        checkUserPhoneCode(getLoginUser().getMobilePhone(), msgCode, PhoneCodeKey.RESET_PHONE);
        checkUserPhoneCode(newPhone, newMsgCode, PhoneCodeKey.RESET_PHONE_NEW);
        userService.updateUserMobile(user.getId(), newPhone);
        delSession(SessionId.RESET_PHONE);
        delSession(SessionId.RESET_PHONE_NEW);
        return ok("修改手机号成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改手机号-发送短信-老手机短信", notes = "修改手机号-发送短信-老手机短信")
    @ResponseBody
    @RequestMapping(value = "oldPhoneSendMsg", method = RequestMethod.POST)
    public ResultEntity oldPhoneSendMsg() throws Exception {
        String code = sendSmsCode(PhoneCodeKey.RESET_PHONE, getLoginUser().getMobilePhone());
        setSession(SessionId.RESET_PHONE, code, 600);// 默认10分钟过期
        return ok("修改手机号-发送短信-老手机短信成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改手机号-发送短信-新手机短信", notes = "修改手机号-发送短信-新手机短信")
    @ResponseBody
    @RequestMapping(value = "newPhoneSendMsg", method = RequestMethod.POST)
    public ResultEntity newPhoneSendMsg(@ApiParam("新手机号") @RequestParam String newPhone) throws Exception {
        String code = sendSmsCode(PhoneCodeKey.RESET_PHONE, newPhone);
        setSession(SessionId.RESET_PHONE, code, 600);// 默认10分钟过期
        return ok("修改手机号-发送短信-新手机短信成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "修改手机号-校验老手机号短信", notes = "修改手机号-校验老手机号短信")
    @ResponseBody
    @RequestMapping(value = "phoneCheckMsg", method = RequestMethod.POST)
    public ResultEntity phoneCheckMsg(@ApiParam("老手机短信验证码") @RequestParam String msgCode) throws Exception {
        checkUserPhoneCode(getLoginUser().getMobilePhone(), msgCode, PhoneCodeKey.RESET_PHONE);
        return ok("修改手机-号校验老手机号-短信成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "个人中心-账号设置-修改登录密码", notes = "修改登录密码")
    @ResponseBody
    @RequestMapping(value = "editPwd", method = RequestMethod.POST)
    public ResultEntity editPwd(@ApiParam("当前密码") @RequestParam(required = true) String oldPwd,
                                @ApiParam("新密码") @RequestParam(required = true) String newPwd) {
        User user = getLoginUser();
        //解密oldPwd 并判断和用户密码对比
        if (!UserModel.staticEncodePwd(UserModel.staticDecryptPwd(oldPwd)).equals(user.getPassword())) {
            throw new BussinessException("当前密码输入有误，请确认后重新输入");
        }
        if (newPwd.equals(oldPwd)) {
            throw new BussinessException("新密码不能和旧密码相同");
        }
        //修改用户密码
        userService.updateByPrimaryKeySelective(new User(u -> {
            u.setId(user.getId());
            u.setPassword(UserModel.staticEncodePwd(UserModel.staticDecryptPwd(newPwd)));
        }));
        //删除缓存用户让用户重新登录
        delSession(SessionId.MEMBER_USER);
        return ok("修改登录密码成功", ResultEntity.SUCCESS);
    }

    @ApiOperation(value = "我的邀请码", notes = "我的邀请码")
    @ResponseBody
    @RequestMapping(value = "myInviteCode", method = RequestMethod.POST)
    public ResultEntity myInviteCode() throws Exception {
        return ok(m -> {
            m.put("code", getLoginUser().getInviteCode());
        });
    }

    @ApiOperation(value = "推广赚钱", notes = "推广赚钱")
    @ResponseBody
    @RequestMapping(value = "toSpread", method = RequestMethod.POST)
    public ResultEntity toSpread() throws Exception {
        return ok(m -> {
            m.put("url", redisService.get(ConfigNID.WEB_SERVER_URL));
            m.put("inviteCode", getLoginUser().getInviteCode());
        });
    }

    @ApiOperation(value = "我的用户", notes = "我的用户")
    @ResponseBody
    @RequestMapping(value = "myUser", method = RequestMethod.POST)
    public ResultEntity myUser(@ModelAttribute BasePageParams basePageParams) throws Exception {
        User user = getLoginUser();
        Map<String, Object> param = new HashMap<>();
        param.put("userId", user.getId());
        param.put("basePageParams", basePageParams);
        Pages<UserModel> pages = userService.selectByPage(basePageParams,
                q -> ((UserMapper) q).findCountForFriendsList(param),
                q -> ((UserMapper) q).findListForFriendsList(param));
        List<UserModel> userModels = pages.getRows();
        if (CollectionUtils.isNotEmpty(userModels)) {
            for (UserModel userModel : userModels) {
                Integer strategyTotal = orderService.selectCount(new Order(t -> {
                    t.setUserId(userModel.getId());
                    t.setDelFlag(User.DELFLAG.NORMAL.code);
                    t.setStatus(Order.STATUS.T7.code);
                }));
                if (null == strategyTotal) {
                    userModel.setStrategyTotal(0);
                } else {
                    userModel.setStrategyTotal(strategyTotal);
                }
                Order order = orderService.selectByOne(userModel.getId());
                if (null == order) {
                    userModel.setStrategyPush(null);
                } else {
                    userModel.setStrategyPush(order.getCreateTime());
                }
            }
        }
        pages.setRows(userModels);
        BigDecimal yesTodayAmount = BigDecimal.ZERO;
        BigDecimal totalAmount = BigDecimal.ZERO;
        Integer userStrategyTotal = orderService.selectCount(new Order(t -> {
            t.setUserId(user.getId());
            t.setDelFlag(Order.DELFLAG.NORMAL.code);
            t.setStatus(Order.STATUS.T7.code);
        }));
        List<Order> userOrder = orderService.selectYesStrategy(user.getId());
        return ok(m -> {
            m.put("pages", pages);
            m.put("yesTodayAmount", yesTodayAmount);
            m.put("totalAmount", totalAmount);
            m.put("generalizeCount", userService.selectCount(new User(t -> {
                t.setInviteId(user.getId());
            })));
            m.put("userStrategyTotal", null == userStrategyTotal ? 0 : userStrategyTotal);
            m.put("userYesStrategy", null == userOrder ? 0 : userOrder.size());
        });
    }

    @ApiOperation(value = "问题反馈", notes = "问题反馈")
    @ResponseBody
    @RequestMapping(value = "suggestion", method = RequestMethod.POST)
    public ResultEntity suggestion(@ApiParam("问题内容") @RequestParam String suggestion) throws Exception {
        if (StringUtils.isBlank(suggestion)) {
            throw new BussinessException("请提交内容");
        } else if (suggestion.length() > 200) {
            throw new BussinessException("内容长度应小于200");
        }
        User user = getLoginUser();
        suggestionService.insert(new Suggestion(t -> {
            t.setUserId(user.getId());
            t.setSuggestion(suggestion);
        }));
        return ok("问题反馈提交成功", ResultEntity.SUCCESS);
    }

}
